/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package suministros.ejb30.DAO;

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import javax.sql.DataSource;
import suministros.ejb30.TO.DetalleOrdenTO;
import suministros.ejb30.TO.DetalleSolicitudCotizacionTO;
import suministros.ejb30.TO.ParametrosConsultaTO;
import suministros.ejb30.TO.ProveedorTO;
import suministros.ejb30.TO.SolicitudCotizacionTO;
import suministros.ejb30.entity.DetalleSolicitudCotizacion;
import suministros.ejb30.entity.DetalleSolicitudCotizacionPK;
import suministros.ejb30.entity.SolicitudCotizacion;
import suministros.ejb30.entity.Tipo;
import suministros.ejb30.helper.Utiles_Convertir;

/**
 *
 * @author Luis_Angel
 */
@Stateless
public class SumiGestionCotizacionesDAO implements SumiGestionCotizacionesDAOLocal {

    @EJB
    private SumiGestionPedidoDAOLocal sumiGestionPedidoDAO;

    @PersistenceUnit(unitName="suministros-pu")
     EntityManagerFactory emf;

    EntityManager em;

    @Resource(name="jdbc/Administracion")
    DataSource dsAdministracion;

     @PostConstruct
      public void inicializaBean()
      {
        this.em = this.emf.createEntityManager();
      }

    @PreDestroy
      public void finalizaBean() {
        this.em.close();
      }

       public List<DetalleSolicitudCotizacionTO> getListaDetallePedidoSuministroSolicitudCotizacion(String cod_pedido) throws Exception {
          Integer tipo_estado =  Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AC")).getIdTablaTipo();
         Query consulta = this.em.createNativeQuery("SELECT dps.Cod_Pedido,s.ID_Suministro, s.descripcion, dps.cantidad_pedida,t1.descripcion_valor,0 as precio  FROM Detalle_Pedido_Suministro dps INNER JOIN Suministros s ON dps.ID_Suministro = s.ID_Suministro inner join Tipo t1 ON s.tipo_unidad_medida=t1.id_tabla_tipo inner join Pedido p on dps.Cod_Pedido=p.Cod_Pedido  where dps.Cod_Pedido='" + cod_pedido + "' and dps.Tipo_Estado_Pedido="+tipo_estado);

         return Utiles_Convertir.convertirToBeanBinding_DetallePedidoSolicitudCotizacion(consulta.getResultList());
    }

    public String getIdSolicitud(SolicitudCotizacion solicitud) throws Exception {
         String retorno = null;
        Connection cnx = null;
        try {
          //Utiles_Fecha fecha = new Utiles_Fecha(orden.getFechaemision());
          cnx = this.dsAdministracion.getConnection();
          CallableStatement csLlamada = cnx.prepareCall("{? = call [dbo].[f_sumi_getcodigoSolicitudCotizacion](?,?,?)}");
          csLlamada.registerOutParameter(1,12);
          csLlamada.setString(2, solicitud.getAno());
          csLlamada.setString(3, solicitud.getMes());
          csLlamada.setString(4, solicitud.getEmpresa().getIdEmpresa());
          csLlamada.execute();
          retorno = csLlamada.getString(1);
        }
        catch (SQLException ex) {
          throw ex;
        } finally {
          try {
            cnx.close();
          } catch (Exception ex) {
            Logger.getLogger(SumiGestionPedidoDAO.class.getName()).log(Level.SEVERE, null, ex);
          }
        }
        return retorno;
    }

    public String insertarSolicitudCotizacion(SolicitudCotizacion solicitud, List<DetalleSolicitudCotizacion> detalle_solicitud) throws Exception {
          String retorno = "";
            EntityTransaction tx = this.em.getTransaction();
            tx.begin();

               try {
                  String codigo = this.getIdSolicitud(solicitud);
                  
                  solicitud.setNroSolicitudCotizacion(codigo);
                  solicitud.setIsAlta(true);
                  solicitud.setFechaOperacion(new Date());
                  this.em.persist(solicitud);
                  this.em.flush();
                  for (DetalleSolicitudCotizacion detalle : detalle_solicitud)
                  {
                    detalle.setDetalleSolicitudCotizacionPK(new DetalleSolicitudCotizacionPK(codigo,detalle.getDetalleSolicitudCotizacionPK().getCorrelativo(),detalle.getDetalleSolicitudCotizacionPK().getCodProveedor()));
                    this.em.persist(detalle);

                  }

                  this.em.flush();
                  tx.commit();
                  retorno = codigo;
                } catch (Exception e) {
                  tx.rollback();
                  throw e;
                }

            return retorno;
    }

    public List<ProveedorTO> buscaSolicitud(String nro_solicitud, String id_empresa) throws Exception {

            SolicitudCotizacion sc = this.em.find(SolicitudCotizacion.class, nro_solicitud);
              if(!sc.isIsAlta()){
                  List<ProveedorTO> retorno = new ArrayList(1);
                    return retorno;
              }

              else{
                Query consulta = this.em.createNativeQuery("SELECT distinct pr.cod_proveedor,pr.razon_social from Detalle_Solicitud_Cotizacion dsc inner join Proveedor pr on dsc.cod_proveedor=pr.cod_proveedor inner join Solicitud_Cotizacion sc on dsc.nro_solicitud_cotizacion = sc.nro_solicitud_cotizacion where sc.nro_solicitud_cotizacion ='" + nro_solicitud + "' and sc.alta=1 and sc.id_empresa='" + id_empresa + "'");
                return Utiles_Convertir.convertirToBeanBinding_Proveedor(consulta.getResultList());
              }
              
         
    }

    public List<DetalleSolicitudCotizacionTO> getDetallesSolicitud(String ruc_proveedor, String nro_solicitud) throws Exception {
        Query consulta = this.em.createNativeQuery("SELECT dsc.Cod_Pedido,s.ID_Suministro, s.descripcion, dsc.cantidad,t1.descripcion_valor,dsc.precio_unitario,dsc.correlativo,dsc.validez_oferta,dsc.tiempo_entrega,dsc.tiempo_garantia,t2.descripcion_valor,t3.descripcion_valor,t4.descripcion_valor,dsc.sub_total,dsc.observacion  FROM Detalle_Solicitud_Cotizacion dsc INNER JOIN Suministros s ON dsc.ID_Suministro = s.ID_Suministro inner join Tipo t1 ON s.tipo_unidad_medida=t1.id_tabla_tipo  left join Tipo t2 ON dsc.tipo_moneda=t2.id_tabla_tipo  left join Tipo t3 ON dsc.plantilla_impuesto=t3.id_tabla_tipo left join Tipo t4 ON dsc.forma_pago=t4.id_tabla_tipo  where dsc.cod_proveedor='" + ruc_proveedor + "' and dsc.nro_solicitud_cotizacion='"+nro_solicitud+"'" );

         return Utiles_Convertir.convertirToBeanBinding_DetallePedidoSolicitudCotizacion1(consulta.getResultList());
    }

    public boolean registrarCotizacion(String ruc_proveedor, String nro_solicitud, List<DetalleSolicitudCotizacionTO> detalles_solicitud,Tipo forma_pago, Tipo impuesto, Tipo moneda) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
            tx.begin();

               try {

                  for (DetalleSolicitudCotizacionTO detalle : detalles_solicitud)
                  {
                    DetalleSolicitudCotizacion dsc= this.em.find(DetalleSolicitudCotizacion.class,new DetalleSolicitudCotizacionPK(nro_solicitud,detalle.getCorrelativo(),ruc_proveedor));
                    dsc.setPrecioUnitario(detalle.getPrecio());
                    dsc.setPlantillaImpuesto(impuesto);
                    dsc.setFormaPago(forma_pago);
                    dsc.setObservacion(detalle.getObservacion());
                    dsc.setTipoMoneda(moneda);
                    dsc.setTiempoEntrega(detalle.getTiempo_entrega());
                    dsc.setTiempoGarantia(detalle.getTiempo_garantia());
                    dsc.setValidezOferta(detalle.getValidez_oferta());
                    dsc.setSubTotal(detalle.getCantidad().multiply(detalle.getPrecio()));
                    this.em.persist(dsc);

                  }

                  this.em.flush();
                  tx.commit();
                  retorno = true;
                } catch (Exception e) {
                  tx.rollback();
                  throw e;
                }
            return retorno;
    }

    public boolean estableceGanador(List<DetalleSolicitudCotizacionTO> detalle_solicitud, String nro_solicitud, String proveedor) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
            tx.begin();

               try {

                  DetalleSolicitudCotizacionTO dscto = detalle_solicitud.get(0);
                  DetalleSolicitudCotizacion dscentity = this.em.find(DetalleSolicitudCotizacion.class,new DetalleSolicitudCotizacionPK(nro_solicitud,dscto.getCorrelativo(),proveedor));
                  BigDecimal monto_total =new BigDecimal("0.0");

                  for (DetalleSolicitudCotizacionTO detalle : detalle_solicitud)
                  {
                    monto_total = monto_total.add(detalle.getSub_total());
                    
                  }
                  
                  SolicitudCotizacion sc = this.em.find(SolicitudCotizacion.class,nro_solicitud);
                 
                  sc.setCodProveedorGanador(proveedor);
                  sc.setValorTotal(monto_total);
                  sc.setTiempoEntrega(dscto.getTiempo_entrega());
                  sc.setTiempoGarantia(dscto.getTiempo_garantia());
                  sc.setValidezOferta(dscto.getValidez_oferta());
                  sc.setPlantillaImpuesto(dscentity.getPlantillaImpuesto().getIdTablaTipo());
                  sc.setFormaPago(dscentity.getFormaPago().getIdTablaTipo());
                  sc.setTipoMoneda(dscentity.getTipoMoneda().getIdTablaTipo());

                  this.em.merge(sc);
                  this.em.flush();
                  tx.commit();
                  retorno = true;
                } catch (Exception e) {
                  tx.rollback();
                  throw e;
                }
            return retorno;
    }

     public List<DetalleSolicitudCotizacionTO> getListaDetallePedidoSuministroSolicitudCotizacion(String cod_pedido, String cod_sumi) throws Exception {
          Integer tipo_estado =  Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AC")).getIdTablaTipo();
         Query consulta = this.em.createNativeQuery("SELECT dps.Cod_Pedido,s.ID_Suministro, s.descripcion, dps.cantidad_pedida,t1.descripcion_valor,0 as precio  FROM Detalle_Pedido_Suministro dps INNER JOIN Suministros s ON dps.ID_Suministro = s.ID_Suministro inner join Tipo t1 ON s.tipo_unidad_medida=t1.id_tabla_tipo inner join Pedido p on dps.Cod_Pedido=p.Cod_Pedido  where dps.Cod_Pedido='" + cod_pedido + "' and dps.Tipo_Estado_Pedido="+tipo_estado + " and dps.id_suministro='" + cod_sumi + "'");

         return Utiles_Convertir.convertirToBeanBinding_DetallePedidoSolicitudCotizacion(consulta.getResultList());
    }

    public List<SolicitudCotizacionTO> getListaCotizacionesAprobadas() throws Exception {
        Query consulta = this.em.createNativeQuery("SELECT sc.nro_solicitud_cotizacion,pro.cod_proveedor,pro.razon_social,sc.valor_total,sc.forma_pago,sc.plantilla_impuesto,sc.tipo_moneda from Solicitud_Cotizacion sc inner join proveedor pro on sc.cod_proveedor_ganador=pro.cod_proveedor where sc.alta=1");
         return Utiles_Convertir.convertirTOSolicitudCotizacionTO(consulta.getResultList());
    }

    public List<DetalleOrdenTO> getListaDetallesPedidoOrdenCotizacion(String nro_solicitud,String proveedor) throws Exception {
        Integer tipo_admin =  Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_administradorTarea", "01")).getIdTablaTipo();
         Integer tipo_estado =  Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AC")).getIdTablaTipo();
         Query consulta = this.em.createNativeQuery("SELECT dps.Cod_Pedido,s.ID_Suministro, s.descripcion, dps.cantidad_pedida,t1.descripcion_valor,dsc.precio_unitario as precio,p.cod_Uni_Organizativa,p.id_cod_presupuestal,p.id_cod_inversion,p.id_cuenta_contable_inversion,p.Cod_CentroCosto,p.id_zona,p.id_localidad,p.id_proyecto,dsc.sub_total  FROM Detalle_Pedido_Suministro dps INNER JOIN Suministros s ON dps.ID_Suministro = s.ID_Suministro inner join Tipo t1 ON s.tipo_unidad_medida=t1.id_tabla_tipo inner join Pedido p on dps.Cod_Pedido=p.Cod_Pedido  inner join detalle_solicitud_cotizacion dsc on dsc.Cod_Pedido=dps.Cod_Pedido  where dsc.nro_solicitud_cotizacion='" + nro_solicitud + "' and dsc.cod_proveedor='"+ proveedor +"' and dsc.id_suministro=dps.id_suministro and dps.Tipo_Estado_Pedido="+tipo_estado+" and dps.id_tipo_administrador_tarea="+tipo_admin);

         return Utiles_Convertir.convertirToBeanBinding_DetallePedidoOrden(consulta.getResultList());
    }

    public SolicitudCotizacionTO getSolicitudCotizacion(String nro_solicitud) throws Exception {
         Query consulta = this.em.createNativeQuery("SELECT sc.nro_solicitud_cotizacion,pro.cod_proveedor,pro.razon_social,sc.valor_total,sc.forma_pago,sc.plantilla_impuesto,sc.tipo_moneda from Solicitud_Cotizacion sc inner join proveedor pro on sc.cod_proveedor_ganador=pro.cod_proveedor where sc.nro_solicitud_cotizacion='" +nro_solicitud +"'");
         return Utiles_Convertir.convertirTOSolicitudCotizacionTO(consulta.getResultList()).get(0);
    }

    public boolean bajaSolicitud(String nro_solicitud) throws Exception {
        boolean retorno = false;
       
        EntityTransaction tx = this.em.getTransaction();
            tx.begin();

         try {
             SolicitudCotizacion sc = this.em.find(SolicitudCotizacion.class, nro_solicitud);

            sc.setIsAlta(false);
            this.em.merge(sc);
            this.em.flush();
             tx.commit();
             retorno = true;

        } catch (Exception e) {
            tx.rollback();
          throw e;
        }

        return retorno;

    }

     public int getNumeroDeCotizaciones(ParametrosConsultaTO parametros) throws Exception {
         Query consulta = this.em.createNativeQuery("select sc.nro_solicitud_cotizacion,dsc.cod_proveedor,sum(sub_total) AS monto,case "+
                                                                                                                                        "when sum(sub_total)=0.00 and sc.cod_proveedor_ganador is null then 'SIN COTIZAR' "+
                                                                                                                                        "when sc.cod_proveedor_ganador is null then 'SIN GANADOR' "+
                                                                                                                                        "when sc.cod_proveedor_ganador=dsc.cod_proveedor then 'GANADOR' "+
                                                                                                                                        "else '-' "+
                                                                                                                                        "end as estado , "+
                                                                                                                                        "case " +
                                                                                                                                           " when sc.cod_proveedor_ganador=dsc.cod_proveedor and o.nro_solicitud_cotizacion is null then '-' " +
                                                                                                                                           " when sc.cod_proveedor_ganador=dsc.cod_proveedor then o.nro_orden " +
                                                                                                                                           " else '-' "+
                                                                                                                                        "end as orden "+
                                                    "from solicitud_cotizacion sc inner join detalle_solicitud_cotizacion dsc on sc.nro_solicitud_cotizacion=dsc.nro_solicitud_cotizacion " +
                                                    "           left join orden o on sc.nro_solicitud_cotizacion=o.nro_solicitud_cotizacion " +
                                                    getCadenaWhere(parametros) +
                                                   " group by sc.nro_solicitud_cotizacion,dsc.cod_proveedor,sc.cod_proveedor_ganador,o.nro_orden,o.nro_solicitud_cotizacion " +
                                                    "order by sc.nro_solicitud_cotizacion desc");
        return consulta.getResultList().size();
    }

    public List<SolicitudCotizacionTO> consultarCotizacion(ParametrosConsultaTO parametros,int pagActual, int pagTamanno) throws Exception {
           
        Query consulta = this.em.createNativeQuery("select sc.nro_solicitud_cotizacion,dsc.cod_proveedor,sum(sub_total) AS monto,case "+
                                                                                                                                        "when sum(sub_total)=0.00 and sc.cod_proveedor_ganador is null then 'SIN COTIZAR' "+
                                                                                                                                        "when sc.cod_proveedor_ganador is null then 'SIN GANADOR' "+
                                                                                                                                        "when sc.cod_proveedor_ganador=dsc.cod_proveedor then 'GANADOR' "+
                                                                                                                                        "else '-' "+
                                                                                                                                        "end as estado , "+
                                                                                                                                        "case " +
                                                                                                                                           " when sc.cod_proveedor_ganador=dsc.cod_proveedor and o.nro_solicitud_cotizacion is null then '-' " +
                                                                                                                                           " when sc.cod_proveedor_ganador=dsc.cod_proveedor then o.nro_orden " +
                                                                                                                                           " else '-' "+
                                                                                                                                        "end as orden "+
                                                    "from solicitud_cotizacion sc inner join detalle_solicitud_cotizacion dsc on sc.nro_solicitud_cotizacion=dsc.nro_solicitud_cotizacion " +
                                                    "           left join orden o on sc.nro_solicitud_cotizacion=o.nro_solicitud_cotizacion " +
                                                    getCadenaWhere(parametros) +
                                                   " group by sc.nro_solicitud_cotizacion,dsc.cod_proveedor,sc.cod_proveedor_ganador,o.nro_orden,o.nro_solicitud_cotizacion " +
                                                    "order by sc.nro_solicitud_cotizacion desc");
        return Utiles_Convertir.convertirTOSolicitudCotizacionTO2(consulta.setFirstResult(pagActual*pagTamanno).setMaxResults(pagTamanno).getResultList());
     }

    public List<SolicitudCotizacionTO> getListaCotizacionesEnEspera(String id_empresa) throws Exception {
        Query consulta = this.em.createNativeQuery("SELECT sc.nro_solicitud_cotizacion from Solicitud_Cotizacion sc  where sc.cod_proveedor_ganador is null and sc.alta=1 and sc.id_empresa='" + id_empresa + "'");
         return Utiles_Convertir.convertirTOSolicitudCotizacionTO1(consulta.getResultList());
    }


    private String getCadenaWhere(ParametrosConsultaTO parametros){
         String cadena_where = "";
        if(parametros.getRuc_proveedor()!=null)
            cadena_where+="where dsc.cod_proveedor = '"+parametros.getRuc_proveedor()+ "' ";
        if(parametros.getAnio()!=null){
            if(cadena_where.length()==0)
                cadena_where+="where sc.ano = '"+parametros.getAnio()+ "' ";
            else
                cadena_where+="and sc.ano = '"+parametros.getAnio()+ "' ";
        }
        if(parametros.getMes()!=null){
            if(cadena_where.length()==0)
                cadena_where+="where sc.mes = '"+parametros.getMes()+ "' ";
            else
                cadena_where+="and sc.mes = '"+parametros.getMes()+ "' ";
        }
        if(parametros.getNro_solicitud_cotizacion()!=null){
            if(cadena_where.length()==0)
                cadena_where+="where sc.nro_solicitud_cotizacion = '"+parametros.getNro_solicitud_cotizacion()+ "' ";
            else
                cadena_where+="and sc.nro_solicitud_cotizacion = '"+parametros.getNro_solicitud_cotizacion()+ "' ";
        }
         if(parametros.getId_empresa()!=null){
            if(cadena_where.length()==0)
                cadena_where+="where sc.id_empresa = '"+parametros.getId_empresa()+ "' ";
            else
                cadena_where+="and sc.id_empresa = '"+parametros.getId_empresa()+ "' ";
        }
        return cadena_where;
   }


    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
 
}
